﻿using DxfMonitor.ViewModel;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DxfMonitor.Data
{
    public class Repository
    {
        public Repository()
        {
        }

        public static DxfFolder CreateOrGetDxfFolder(string folderFull)
        {
            using (DxfDbContext dbContext = new DxfDbContext())
            {
                DxfFolder dxfFolder = dbContext.DxfFolders.Include(x => x.DxfFiles).FirstOrDefault(x => x.FolderFull == folderFull);
                if (dxfFolder == null)
                {
                    dxfFolder = new DxfFolder();
                    dxfFolder.FolderFull = folderFull;
                    dbContext.DxfFolders.Add(dxfFolder);
                    dbContext.SaveChanges();
                }
                if (dxfFolder.DxfFiles != null)
                    Debug.WriteLine($"{folderFull} files = {dxfFolder.DxfFiles.Count}");
                return dxfFolder;
            }
        }

        public static DxfFolder CreateOrGetDxfFolderWithDbContext(DxfDbContext dbContext, string folderFull)
        {

            DxfFolder dxfFolder = dbContext.DxfFolders.Include(x => x.DxfFiles).FirstOrDefault(x => x.FolderFull == folderFull);
            if (dxfFolder == null)
            {
                dxfFolder = new DxfFolder();
                dxfFolder.FolderFull = folderFull;
                dbContext.DxfFolders.Add(dxfFolder);
                dbContext.SaveChanges();
            }
            if (dxfFolder.DxfFiles != null)
                Debug.WriteLine($"{folderFull} files = {dxfFolder.DxfFiles.Count}");
            return dxfFolder;

        }

        private static DxfPair CreateEmptyPair()
        {
            using (DxfDbContext dbContext = new DxfDbContext())
            {
                DxfFolder dxfFolder = dbContext.DxfFolders.FirstOrDefault(x => string.IsNullOrWhiteSpace(x.FolderFull));
                if (dxfFolder == null)
                {
                    dxfFolder = new DxfFolder();
                    dbContext.DxfFolders.Add(dxfFolder);
                }
                DxfPair dxfPair = new DxfPair()
                {
                    Guid = System.Guid.NewGuid().ToString(),
                    CurrentFolder = dxfFolder,
                    LastFolder = dxfFolder
                };
                dbContext.DxfPairs.Add(dxfPair);
                dbContext.SaveChanges();
                return dxfPair;
            }
        }

        public static IList<DxfPair> LoadAllDxfPairs()
        {
            using (DxfDbContext dbContext = new DxfDbContext())
            {
                int pairCnt = dbContext.DxfPairs.Count();
                for (int i = pairCnt; i < 15; i++)
                {
                    CreateEmptyPair();
                }
                var pairs = dbContext.DxfPairs.Include(x => x.LastFolder).Include(x => x.CurrentFolder).ToList();
                return pairs;
            }
        }


        public static void ClearPair(FolderPairViewModel pairViewModel)
        {
            using (DxfDbContext dbContext = new DxfDbContext())
            {
                DxfFolder dxfFolder = dbContext.DxfFolders.FirstOrDefault(x => string.IsNullOrWhiteSpace(x.FolderFull));
                if (dxfFolder == null)
                {
                    dxfFolder = new DxfFolder();
                    dbContext.DxfFolders.Add(dxfFolder);
                }
                DxfPair dxfPair = dbContext.DxfPairs.Include(x => x.LastFolder).Include(x => x.CurrentFolder).First(x => x.Guid == pairViewModel.Guid);
                dxfPair.IsChecked = false;
                dxfPair.LastFolder = dxfFolder;
                dxfPair.CurrentFolder = dxfFolder;
                dbContext.SaveChanges();
            }
        }

        public static void SavePairAndFolder(FolderPairViewModel pairViewModel)
        {
            using (DxfDbContext dbContext = new DxfDbContext())
            {
                DxfPair dxfPair = dbContext.DxfPairs.Include(x => x.LastFolder).Include(x => x.CurrentFolder).First(x => x.Guid == pairViewModel.Guid);
                dxfPair.IsChecked = pairViewModel.IsChecked;
                if (Directory.Exists(pairViewModel.CurrentFolderFull))
                {
                    DxfFolder dxfFolder = CreateOrGetDxfFolderWithDbContext(dbContext, pairViewModel.CurrentFolderFull);
                    dxfPair.CurrentFolder = dxfFolder;
                }
                if (Directory.Exists(pairViewModel.LastFolderFull))
                {
                    DxfFolder dxfFolder = CreateOrGetDxfFolderWithDbContext(dbContext, pairViewModel.LastFolderFull);
                    dxfPair.LastFolder = dxfFolder;
                }

                dbContext.SaveChanges();
            }
        }

        public static DateTime QueryFolderBaseDate(string lastFolderFull)
        {
            using (DxfDbContext dbContext = new DxfDbContext())
            {
                DxfFolder dxfFolder = dbContext.DxfFolders.FirstOrDefault(x => x.FolderFull == lastFolderFull);
                if (dxfFolder == null)
                {
                    dxfFolder = new DxfFolder();
                    dbContext.DxfFolders.Add(dxfFolder);
                }
                return dxfFolder.BaseDate;
            }
        }
        public static void DeleteTooOld()
        {
            using (DxfDbContext dbContext = new DxfDbContext())
            {
                var curs = dbContext.DxfPairs.Include(x => x.CurrentFolder).Select(x => x.CurrentFolder);
                var lasts = dbContext.DxfPairs.Include(x => x.LastFolder).Select(x => x.LastFolder);
                var usedFolders = new HashSet<DxfFolder>(curs).Union(new HashSet<DxfFolder>(lasts));
                foreach (DxfFolder dxfFolder in dbContext.DxfFolders.Include(x => x.DxfFiles)
                    .Where(x => !usedFolders.Contains(x)))
                {
                    if (DateTime.Now.Subtract(dxfFolder.BaseDate).TotalDays < 30)
                        continue;
                    foreach (DxfFile dxfFile in dxfFolder.DxfFiles)
                    {
                        dbContext.DxfFiles.Remove(dxfFile);
                    }
                    dbContext.DxfFolders.Remove(dxfFolder);
                }
                dbContext.SaveChanges();
            }
        }

        public static IList<DxfHistoryStatus> QueryLastDxfHistoryStatuses(string lastFolderFull, out DateTime lastUpdateDate)
        {
            using (DxfDbContext dbContext = new DxfDbContext())
            {
                var folder = dbContext.DxfFolders.Include(x => x.DxfFiles).First(x => x.FolderFull == lastFolderFull);
                lastUpdateDate = folder.BaseDate;
                var last = folder.DxfFiles.Select(x => new DxfHistoryStatus(x)).ToList();
                return last;
            }
        }

        public static void SaveLasts(IList<DxfHistoryStatus> current, string currentFolderFull, DateTime baseDate)
        {
            using (DxfDbContext dbContext = new DxfDbContext())
            {
                foreach (DxfFile dxfFile in dbContext.DxfFiles.Include(x => x.Folder).Where(x => x.Folder.FolderFull == currentFolderFull))
                {
                    dbContext.DxfFiles.Remove(dxfFile);
                }
                DxfFolder dxfFolder = dbContext.DxfFolders.FirstOrDefault(x => x.FolderFull == currentFolderFull);
                if (dxfFolder == null)
                {
                    dxfFolder = new DxfFolder();
                    dxfFolder.FolderFull = currentFolderFull;
                    dbContext.DxfFolders.Add(dxfFolder);
                }
                dxfFolder.BaseDate = baseDate;
                foreach (DxfHistoryStatus historyStatus in current)
                {
                    dbContext.DxfFiles.Add(new DxfFile()
                    {
                        Folder = dxfFolder,
                        RelativePath = historyStatus.RelativePath,
                        ModifiedDate = historyStatus.ModifiedDate
                    });
                }
                dbContext.SaveChanges();

            }

        }
    }
}
